package com.symaster.backups.util;

import com.symaster.common.animation.Curve;
import com.symaster.common.geom.entity.LineSegment;
import com.symaster.common.geom.entity.Point;
import com.symaster.common.geom.util.PointUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author yinmiao
 * @version 2023/12/7
 */
public class AnimationUtil {
    private static final float accuracy = 0.000000001f; // 曲线计算精度

    public static double getPoint(Curve curve, double time) {

        List<LineSegment> lineSegments = curve.toLineSegments();
        Point startPointBus = lineSegments.get(0).getStartPoint();
        Point endPointBus = lineSegments.get(lineSegments.size() - 1).getEndPoint();

        if (startPointBus.getX() > accuracy || startPointBus.getY() < 1.0f - accuracy ||
                endPointBus.getX() < 1.0f - accuracy || endPointBus.getY() > accuracy) {
            lineSegments.add(0, new LineSegment(new Point(0, 0), startPointBus));
            lineSegments.add(new LineSegment(endPointBus, new Point(1, 0)));
        }

        List<LineSegment> lineSegments1 = new ArrayList<>();
        for (LineSegment lineSegment : lineSegments) {
            Point lineStartPoint = lineSegment.getStartPoint();
            Point lineEndPoint = lineSegment.getEndPoint();

            if (Math.abs(lineStartPoint.getX() - time) <= accuracy) {
                return lineStartPoint.getY();
            }

            if (Math.abs(lineEndPoint.getX() - time) <= accuracy) {
                return lineEndPoint.getY();
            }

            double max = Math.max(lineStartPoint.getX(), lineEndPoint.getX());
            double min = Math.min(lineStartPoint.getX(), lineEndPoint.getX());

            if (min < time + accuracy && max > time - accuracy) {
                lineSegments1.add(lineSegment);
            }
        }

        if (lineSegments1.isEmpty()) {
            return 1.0D;
        }

        LineSegment lineSegment1 = new LineSegment(new Point(time, -1), new Point(time, 2));
        for (LineSegment lineSegment : lineSegments1) {
            Point crossPoint = PointUtil.getCrossPoint(lineSegment, lineSegment1);
            if (crossPoint != null) {
                return 1.0 - crossPoint.getY();
            }
        }
        return 1.0D;
    }
}
